/**
 * 用来处理父组件向子组件绑定事件
 * 将v-on:event, @event， 添加到子组件的$listeners中并返回
 */
import {
    getListenerName,
    getProps,
    getCorrectedPath
} from "../../../../utils/index";
import { PropsResult, Scope } from "../../../../typings/traverse";
import { setGoalData } from '../../../../utils/getGoalData';
function createListeners(
  $methods: Record<string, Function>,
  element: Element,
) {
    let listener: Record<string, Function> = {};
    Object.values(element.attributes).forEach(item => {
        const { name, value } = item;
        let listenerName = getListenerName(name);
        if (listenerName) {
            listener[listenerName] = $methods[value];
        }
    })
    return listener;
}

/**
 * 在设置:attr.sync时，自动把update:attr
 * 子组件修改父组件，事件绑定到listener
 */
function autoSetPropsSyncListener($data: Record<string, any>, ele: Element, listeners: Record<string, Function>, props: Record<string, Function>, scope?: Scope) {
    Object.keys(props).forEach(key => {
        let propGoal: Partial<PropsResult> = getProps(ele, key, true);
        const { path } = propGoal;
        if (path) {
            let correctPath = getCorrectedPath(path, scope);
            listeners[`update:${key}`] = (val: any) => {
                setGoalData($data, correctPath, val);
            }
        }
    })
}

interface DealGoal {
    $data: Record<string, any>;
    $methods: Record<string, Function>;
}
function getListeners(goal: DealGoal, ele: Element, props?: Record<string, Function>, scope?: Scope) {
    const { $data, $methods } = goal;
    let listeners = createListeners($methods, ele);
    if (props) {
        autoSetPropsSyncListener($data, ele, listeners, props, scope);
    }
    return listeners;
}

export { getListeners }
